home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 May: Tool Chest / Developer CD Series Tool Chest (Apple Computer)(May 1999).iso / Tool Chest / Development Kits / MPW etc / MPW-PR / MPW / Examples / SIOWExamples / Count.c next >
Encoding:
C/C++ Source or Header  |  1998-12-10  |  4.7 KB  |  238 lines  |  [TEXT/MPS ]

  1. /*------------------------------------------------------------------------------
  2.  
  3. NAME
  4.       Count -- count lines and characters
  5.  
  6.  
  7. DESCRIPTION
  8.       "Count" counts the lines and characters in its input, and writes the
  9.         counts to standard output.  If more than one file is specified, separate
  10.         counts are written for each file, one per line, followed by the file name. 
  11.         A total is also written following the list of files.
  12.         
  13. COPYRIGHT
  14.       Copyright Apple Computer, Inc. 1985-1994
  15.         All rights reserved.
  16.  
  17. ------------------------------------------------------------------------------*/
  18.  
  19. #include <Types.h>
  20. #include <ctype.h>
  21. #include <fcntl.h>
  22. #include <string.h>
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25.  
  26. enum
  27. {
  28.     kInputSize =    (1024*8),
  29.     kLimitFileNames = 1000
  30. };
  31.  
  32. /* Variables local to this file */
  33.  
  34. static    Boolean    optionsSpecified = false;
  35. static    Boolean    lineOption = false;
  36. static    Boolean    charOption = false;
  37.  
  38. struct counts 
  39. {
  40.     long    lines;
  41.     long    characters;
  42. };
  43.  
  44. static void count( int input, struct counts* cnts )
  45. {
  46.     char                    c;
  47.     char                    *ptr;
  48.     long                    lines = 0;
  49.     long                    characters = 0;
  50.     long                    charsRead;
  51.     char                    inputBuffer[kInputSize + 1];
  52.  
  53.     while ( ( charsRead = read( input, inputBuffer, kInputSize )) > 0 )
  54.     {
  55.         ptr = inputBuffer;
  56.         inputBuffer[charsRead] = 0;
  57.         characters += charsRead;
  58.         while ( (c = *ptr++) != 0 || ptr <= &inputBuffer[charsRead] )
  59.         {
  60.             if ( c == '\n' ) 
  61.             {
  62.                 lines++;
  63.             }
  64.         }
  65.     }
  66.     if ( characters > 0 && *(ptr-2) != '\n' )
  67.     {
  68.         lines++;
  69.     }
  70.    cnts->lines = lines;
  71.     cnts->characters = characters;
  72. }
  73.  
  74. static void printTitles( void )
  75. {
  76.     if ( optionsSpecified == false || lineOption == true ) 
  77.     {
  78.         printf( "%7s ", "lines" );
  79.     }
  80.     if (optionsSpecified == false || charOption == true) 
  81.     {
  82.         printf( "%9s ", "chars" );
  83.     }
  84.     printf("filename\n");
  85. }
  86.  
  87. static void printCnt( char *name, struct counts cnts )
  88. {
  89.     if (optionsSpecified == false || lineOption == true) 
  90.     {
  91.         printf( "%7ld ", cnts.lines );
  92.     }
  93.     if (optionsSpecified == false || charOption == true) 
  94.     {
  95.         printf( "%9ld ", cnts.characters );
  96.     }
  97.     if ( name != NULL )
  98.     {
  99.         printf("%s", name );
  100.     }
  101.     printf( "\n" );
  102. }
  103.  
  104. int main ( int argc, char* argv[] )
  105. {
  106.     int                    input;
  107.     char                    request[2048]; /* maximum line length that could be expected from gets() */
  108.     long                    lcount = 0;
  109.     long                    files = argc - 1;
  110.     char*                    fileNames[kLimitFileNames];
  111.     long                    done;
  112.     struct    counts    cnts;
  113.     struct    counts    total;
  114.     Boolean                validRequest = false;
  115.     char*                    getsval;
  116.  
  117.     if ( argc <= 1 )
  118.     {
  119.         printf("Note: You can drag text files onto this application's icon in the Finder\n");
  120.         printf("in order to count the lines or characters in those files.\n");
  121.         printf("Make sure Count is not already running when you drag those icons!\n\n");
  122.  
  123.         printf("Enter filenames, one per line, end with a blank line\n");    
  124.  
  125.         files = 0;
  126.         do    {
  127.             getsval = gets( request );
  128.             if ( request[0] == '\0' || getsval == NULL ) /* empty string or EOF */
  129.             {
  130.                 break;
  131.             }
  132.             else
  133.             {
  134.                 fileNames[files] = malloc( strlen(request) + 1 );
  135.                 if ( fileNames[files] == NULL )
  136.                 {
  137.                     break;
  138.                 }
  139.                 else
  140.                 {
  141.                     strcpy( fileNames[files], request );
  142.                     files++;
  143.                 }
  144.             }
  145.         } while ( files < kLimitFileNames );
  146.  
  147.         if ( files == 0 )
  148.         {
  149.             printf("\ndone\n");
  150.             return -1;
  151.         }
  152.     }
  153.     else
  154.     {
  155.         int i;
  156.         printf("%s\n", argv[0] );
  157.         for ( i = 1; i < argc; i++ )
  158.         {
  159.             fileNames[i-1] = argv[i];
  160.             printf( "    '%s'\n", argv[i] );
  161.         }
  162.     }
  163.     printf("\n");
  164.  
  165.     printf("Report desired (C[haracters], L[ines], B[oth]:");
  166.  
  167.     do {
  168.         getsval = gets( request );
  169.         if ( getsval == NULL ) /* EOF */
  170.         {
  171.             validRequest = true;
  172.         }
  173.         else if ( *request == 'c' || *request == 'C' ) 
  174.         {
  175.             optionsSpecified = charOption = true;
  176.             validRequest = true;
  177.         } 
  178.         else if ( *request == 'l' || *request == 'L' ) 
  179.         {
  180.             optionsSpecified = lineOption = true;
  181.             validRequest = true;
  182.         } 
  183.         else if ( *request == 'b' || *request == 'B' ) 
  184.         {
  185.             validRequest = true;
  186.         }
  187.         else 
  188.         {
  189.             printf("expecting C, L, or B, please try again: ");
  190.         }
  191.     } while ( validRequest == false );
  192.     
  193.     printf("\n");
  194.     
  195.     total.lines = total.characters = done = 0;
  196.     
  197.     if ( files >= 1 )
  198.     {
  199.         printTitles();
  200.     }
  201.     for ( lcount = 0; lcount < files; lcount++ )
  202.     {
  203.         input = open( fileNames[lcount], O_RDONLY );
  204.  
  205.         if ( input >= 0 ) 
  206.         {
  207.             count( input, &cnts );
  208.             close( input );
  209.             total.lines += cnts.lines;
  210.             total.characters += cnts.characters;
  211.             printCnt( fileNames[lcount], cnts );
  212.             done++;
  213.         } 
  214.         else 
  215.         {
  216.             fprintf( stderr, "### - Unable to open file %s.\n", fileNames[lcount] );
  217.         }
  218.     }
  219.  
  220.     if ( done > 1 ) 
  221.     {
  222.         printCnt( "Total", total );
  223.         printf("%ld files\n", done );
  224.     }
  225.  
  226.     if ( argc <= 1 ) /* we used malloc in this case */
  227.     {
  228.         int     i;
  229.         for ( i = 0; i < files; i++ )
  230.         {
  231.             free( fileNames[i] ); /* be nice, clean up heap */
  232.         }
  233.     }
  234.  
  235.     printf( "\ndone\n" );
  236.     return 0;
  237. }
  238.